Skip to content

fix: Use raw string values instead of repr() for str types in display_string#383

Open
kgilpin wants to merge 4 commits intofeat/display-labeled-paramsfrom
fix/strip-repr-quotes-from-strings
Open

fix: Use raw string values instead of repr() for str types in display_string#383
kgilpin wants to merge 4 commits intofeat/display-labeled-paramsfrom
fix/strip-repr-quotes-from-strings

Conversation

@kgilpin
Copy link
Copy Markdown
Contributor

@kgilpin kgilpin commented Mar 31, 2026

  • Replace isinstance(val, str) with issubclass(type(val), str) to avoid __class__ lookups on proxy/lazy objects
  • Update the display_string docstring/comment to reflect that str types return raw values (not repr())
  • Verify all tests pass

…_string

When APPMAP_DISPLAY_PARAMS=true, repr() wraps string values in quotes
(e.g. 'my-api-key'), which breaks the scanner's secret-in-log substring
matching. By using the raw string value directly for str types, the
recorded value matches what appears in log messages, enabling proper
secret leak detection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adjusts AppMap parameter/return-value rendering so str values are recorded as their raw string content (not repr()-quoted), improving consistency with log output and enabling reliable secret-in-log substring matching.

Changes:

  • Update display_string to return raw str values instead of repr(val) for strings.
  • Update unit tests to assert raw string values for parameters/return values.
  • Update JSON “expected” AppMap fixtures to match the new string formatting.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
_appmap/event.py Changes display_string to emit raw str values instead of repr() output.
_appmap/test/web_framework.py Updates web framework capture assertions to expect raw string values.
_appmap/test/test_params.py Updates parameter-capture assertions/parameterized expectations for str values.
_appmap/test/test_http.py Updates HTTP client capture assertions for raw string query param values.
_appmap/test/test_events.py Updates labeled params/return value assertions and comment to reflect raw strings.
_appmap/test/data/unittest/expected/unittest.appmap.json Updates expected recorded parameter/return str values (and formatting) to raw strings.
_appmap/test/data/unittest/expected/unittest-no-test-cases.appmap.json Updates expected recorded str values to raw strings.
_appmap/test/data/unittest/expected/pytest.appmap.json Updates expected recorded str values to raw strings.
_appmap/test/data/pytest/expected/pytest-numpy2.appmap.json Updates expected recorded str return values to raw strings.
_appmap/test/data/pytest/expected/pytest-numpy2-no-test-cases.appmap.json Updates expected recorded str return values to raw strings.
_appmap/test/data/pytest/expected/pytest-numpy1.appmap.json Updates expected recorded str return values to raw strings.
_appmap/test/data/pytest/expected/pytest-numpy1-no-test-cases.appmap.json Updates expected recorded str return values to raw strings.
_appmap/test/data/expected.appmap.json Updates expected recorded str parameter/return values (including newline escaping) to raw strings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

_appmap/event.py Outdated
if _should_display(has_labels):
try:
value = repr(val)
value = val if isinstance(val, str) else repr(val)
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using isinstance(val, str) here can trigger class lookups on proxy/lazy objects (the file already avoids isinstance for this reason in _is_list_or_dict), potentially causing side effects or premature evaluation when params display is enabled. Consider avoiding isinstance and instead check the real type (e.g., type(val) is str or issubclass(type(val), str)) before returning the raw value.

Suggested change
value = val if isinstance(val, str) else repr(val)
val_type = type(val)
value = val if (val_type is str or issubclass(val_type, str)) else repr(val)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about:

issubclass(type(val), str)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to issubclass(type(val), str) in commit 622ec72.

_appmap/event.py Outdated
Comment on lines +59 to +64
if _should_display(has_labels):
try:
value = repr(val)
value = val if isinstance(val, str) else repr(val)
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment above still states that parameter display uses repr() to compute a string value, but the implementation now returns the raw value for str types. Please update the comment to reflect the new behavior so it doesn't mislead future readers.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the comment in commit 622ec72 to clarify that str types are returned as-is and other types use repr().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
appmap-python pytest

# Also works for quick local iteration on non-subprocess tests
APPMAP=true .venv/bin/python -m pytest _appmap/test/test_events.py
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note many tests require APPMAP_DISPLAY_PARAMS=true (which tox sets across the board).

Also note uv run is an alternative to using venv directly.

Copy link
Copy Markdown
Contributor

@dividedmind dividedmind left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. We went back and forth on whether strings should be represented in maps verbatim or as a representation; the scanner usage does finally provide a good argument on one over the other.

The test is also a good addition.

Before merging, please:

  • fixup the issubclass and comment fix into the main feature commit,
  • amend the main feature commit message to include BREAKING CHANGE: note; this changes the format of the stringified parameters.

One thing I wonder: since we're special casing strings, does it make sense to always capture them, regardless of appmap_display_params value? If it's a string, there is should be no risk of extra serialization overhead. Two potential pitfalls: 1) making sure the class is also always captured in this case, 2) do we want to truncate to avoid putting huge strings in the appmap?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants